package com.focusai.efairy.business.location;

import com.amap.api.fence.PoiItem;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.services.core.LatLonPoint;
import com.focusai.efairy.EFApplication;
import com.focusai.efairy.model.location.Location;
import com.focusai.efairy.model.location.LocationCallback;
import com.focusai.efairy.model.location.LocationManager;
import com.focusai.efairy.utils.DateUtils;
import com.focusai.efairy.utils.log.Log;

/**
 * 高德定位 定位SDK错误码对照表：http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode
 */
public class AMapLocationManager implements LocationManager {
    private static final String TAG = "AMapLocationManager";

    private LocationCallback locationCallback;
    private LocationListener locationListener = new LocationListener();
    private volatile boolean isStarted;

    private AMapLocationClient locationClient;

    public AMapLocationManager() {
    }

    @Override
    public void setLocationCallback(LocationCallback lc) {
        this.locationCallback = lc;
    }

    @Override
    public void startLocation() {
        startLocation(false);
    }

    @Override
    public void startLocation(boolean checkMockLocation) {
        Log.I(TAG, "开始定位");
        isStarted = true;
        initLocationClient();
        locationClient.startLocation();
    }

    @Override
    public void stopLocation() {
        Log.I(TAG, "停止定位");
        if (locationClient != null) {
            locationClient.stopLocation();
            destroyLocation();
        }
        isStarted = false;
    }

    @Override
    public boolean isStarted() {
        return isStarted;
    }

    @Override
    public void setLocationMode(int mode) {
    }

    private void initLocationClient() {
        destroyLocation();

        AMapLocationClientOption locationOption = new AMapLocationClientOption();
        // 设置是否需要显示地址信息（逆地理编码）
        locationOption.setNeedAddress(true);

        /**
         * 设置是否优先返回GPS定位结果，如果30秒内GPS没有返回定位结果则进行网络定位
         * 注意：只有在高精度模式下的单次定位有效，其他方式无效
         */
//        locationOption.setGpsFirst(true); // 太慢

        // 设置是否开启缓存
        locationOption.setLocationCacheEnable(false);
        // 设置是否单次定位
        locationOption.setOnceLocation(true);
        //设置是否等待设备wifi刷新，如果设置为true,会自动变为单次定位，持续定位时不要使用
        locationOption.setOnceLocationLatest(true);
        //设置是否使用传感器
        locationOption.setSensorEnable(true);
        // 设置网络请求超时时间
        locationOption.setHttpTimeOut(30 * DateUtils.ONE_SECOND);

        locationClient = new AMapLocationClient(EFApplication.getContext());
        locationClient.setLocationOption(locationOption);

        locationClient.setLocationListener(locationListener);
    }

    private void destroyLocation() {
        if (locationClient != null) {
            locationClient.unRegisterLocationListener(locationListener);
            locationClient.onDestroy();
            locationClient = null;
        }
    }

    private class LocationListener implements AMapLocationListener {

        @Override
        public void onLocationChanged(AMapLocation loc) {
            Log.I(TAG, "onLocationChanged：" + loc);

            if (!isStarted()) {
                return;
            }

            if (loc != null && loc.getErrorCode() == 0) {
                if (locationCallback != null) {
                    locationCallback.locationSuccess(aMapLocationToLocation(loc));
                }
            } else {
                String errorMessage = "高德定位";
                int errorCode = -998;
                if (loc != null) {
                    errorCode = loc.getErrorCode();
                    errorMessage = loc.getErrorInfo();
                }
                if (locationCallback != null) {
                    locationCallback.locationFail(errorCode, errorMessage);
                }
            }
            stopLocation();
        }
    }

    @Override
    public int getLocationType() {
        return 0;
    }

    private Location aMapLocationToLocation(AMapLocation loc) {
        Location kdLocation = new Location();
        kdLocation.setCity(loc.getCity());
        kdLocation.setProvince(loc.getProvince());
        kdLocation.setDistrict(loc.getDistrict());
        kdLocation.setStreet(loc.getStreet());
        kdLocation.setFeatureName(loc.getPoiName());
        kdLocation.setLatitude(loc.getLatitude());
        kdLocation.setLongitude(loc.getLongitude());
        kdLocation.setAddress(loc.getAddress());
        return kdLocation;
    }

    public static Location poiItemToLocation(PoiItem item) {
        Location kdLocation = new Location();
        kdLocation.setCity(item.getCity());
        kdLocation.setProvince(item.getProvince());
        kdLocation.setDistrict(item.getAdname());
        kdLocation.setFeatureName(item.getPoiName());
        kdLocation.setLatitude(item.getLatitude());
        kdLocation.setLongitude(item.getLongitude());
        kdLocation.setAddress(item.getAddress());
        return kdLocation;
    }
    public static Location spoiItemToLocation(com.amap.api.services.core.PoiItem item) {
        Location kdLocation = new Location();
        kdLocation.setCity(item.getCityName());
        kdLocation.setProvince(item.getProvinceName());
        kdLocation.setDistrict(item.getAdName());
        kdLocation.setFeatureName(item.getBusinessArea());
        LatLonPoint enter = item.getLatLonPoint();
//        LatLonPoint e = item.getLatLonPoint();
        kdLocation.setLatitude(enter.getLatitude());
        kdLocation.setLongitude(enter.getLongitude());
        kdLocation.setAddress(item.getTitle());
        kdLocation.setStreet(item.getSnippet());
        return kdLocation;
    }
}
